package com.ruoyi.sso.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.sso.domain.SsoWxToken;
import com.ruoyi.sso.domain.SsoWxUser;
import com.ruoyi.sso.domain.SsoWyUrl;
import com.ruoyi.sso.service.ISsoWxTokenService;
import com.ruoyi.sso.service.ISsoWxUserService;
import com.ruoyi.sso.service.ISsoWyUrlService;
import com.ruoyi.sso.util.ApiUserUtils;
import com.ruoyi.sso.util.CommonUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * sso微信用户Controller
 * 
 * @author zsj
 * @date 2020-01-07
 */
@Controller
@RequestMapping("/sso/wxUser")
public class SsoWxUserController extends BaseController
{
    private String prefix = "sso/wxUser";

    @Autowired
    private ISsoWxUserService ssoWxUserService;

	@Autowired
	private ISsoWxTokenService ssoWxTokenService;

	@Autowired
	private ISsoWyUrlService ssoWyUrlService;

	@Autowired
	private ApiUserUtils apiUserUtils;

	@Autowired
	HttpServletRequest request;

	@Autowired
	HttpServletResponse response;
	
    @RequiresPermissions("sso:wxUser:view")
    @GetMapping()
    public String wxUser()
    {
        return prefix + "/wxUser";
    }

    /**
     * 查询sso微信用户列表
     */
    @RequiresPermissions("sso:wxUser:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(SsoWxUser ssoWxUser)
    {
        startPage();
        List<SsoWxUser> list = ssoWxUserService.selectSsoWxUserList(ssoWxUser);
        return getDataTable(list);
    }

    /**
     * 导出sso微信用户列表
     */
    @RequiresPermissions("sso:wxUser:export")
    @Log(title = "sso微信用户", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(SsoWxUser ssoWxUser)
    {
        List<SsoWxUser> list = ssoWxUserService.selectSsoWxUserList(ssoWxUser);
        ExcelUtil<SsoWxUser> util = new ExcelUtil<SsoWxUser>(SsoWxUser.class);
        return util.exportExcel(list, "wxUser");
    }

    /**
     * 新增sso微信用户
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存sso微信用户
     */
    @RequiresPermissions("sso:wxUser:add")
    @Log(title = "sso微信用户", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(SsoWxUser ssoWxUser)
    {
        return toAjax(ssoWxUserService.insertSsoWxUser(ssoWxUser));
    }

    /**
     * 修改sso微信用户
     */
    @GetMapping("/edit/{wxUserId}")
    public String edit(@PathVariable("wxUserId") Long wxUserId, ModelMap mmap)
    {
        SsoWxUser ssoWxUser = ssoWxUserService.selectSsoWxUserById(wxUserId);
        mmap.put("ssoWxUser", ssoWxUser);
        return prefix + "/edit";
    }

    /**
     * 修改保存sso微信用户
     */
    @RequiresPermissions("sso:wxUser:edit")
    @Log(title = "sso微信用户", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(SsoWxUser ssoWxUser)
    {
        return toAjax(ssoWxUserService.updateSsoWxUser(ssoWxUser));
    }

    /**
     * 删除sso微信用户
     */
    @RequiresPermissions("sso:wxUser:remove")
    @Log(title = "sso微信用户", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(ssoWxUserService.deleteSsoWxUserByIds(ids));
    }
    
    /**
	 * 微信登录
	 */
	@ApiOperation(value = "微信登录")
	@Log(title = "sso微信用户", businessType = BusinessType.GRANT)
	@PostMapping("login_by_weixin")
	@ResponseBody
	public Object loginByWeixin(HttpServletRequest request) {

		String code = request.getParameter("wxcode");
		String userInfoJson = request.getParameter("userInfo");

		SsoWxUser wxUser;
		if (StrUtil.isNotBlank(userInfoJson)) {
			wxUser = JSON.parseObject(userInfoJson, SsoWxUser.class);
		} else {
			// 未有用户授权
			wxUser = new SsoWxUser();
			wxUser.setNickName("微信用户" + IdUtil.fastSimpleUUID());
			wxUser.setGender(0);
		}

		if (null == wxUser || null == code) {
			return toResponsFail("登录失败");
		}

		Map<String, Object> resultObj = new HashMap<String, Object>();
		//
		SsoWxUser userInfo = wxUser;

		// ApiUserUtils apiUserUtils = new ApiUserUtils();
		// 获取openid
		String requestUrl = apiUserUtils.getWebAccess(code);// 通过自定义工具类组合出小程序需要的登录凭证 code
		logger.info("》》》组合token为：" + requestUrl);
		JSONObject sessionData = CommonUtil.httpsRequest(requestUrl, "GET", null);

		if (null == sessionData || StrUtil.isBlank(sessionData.getString("openid"))) {
			return toResponsFail("登录失败");
		}
		// 验证用户信息完整性
//		String sha1 = CommonUtil.getSha1(fullUserInfo.getRawData() + sessionData.getString("session_key"));
//		if (!fullUserInfo.getSignature().equals(sha1)) {
//			return toResponsFail("登录失败");
//		}
		Date nowTime = new Date();
		SsoWxUser userVo = ssoWxUserService.queryByOpenId(sessionData.getString("openid"));
		String xff = request.getHeader("X-Real-IP");
		if (xff == null) {
			xff = request.getHeader("x-forwarded-for");
			if (xff == null) {
				xff = "8.8.8.8";
			}
		}

		if (null == userVo) {
			userVo = new SsoWxUser();
			userVo.setRegisterTime(nowTime);
			userVo.setRegisterIp(xff);
			userVo.setLastLoginIp(userVo.getRegisterIp());
			userVo.setLastLoginTime(userVo.getRegisterTime());
			userVo.setWeixinOpenid(sessionData.getString("openid"));
			userVo.setAvatarUrl(userInfo.getAvatarUrl());
			// 性别 0：未知、1：男、2：女
			userVo.setGender(userInfo.getGender());
			userVo.setNickName(userInfo.getNickName());
			ssoWxUserService.insertSsoWxUser(userVo);
		} else {
			userVo.setRegisterTime(nowTime);
			userVo.setLastLoginIp(xff);
			userVo.setLastLoginTime(nowTime);
			ssoWxUserService.updateSsoWxUser(userVo);
		}

		Map<String, Object> tokenMap = ssoWxTokenService.createToken(userVo.getWxUserId());
		String token = MapUtil.get(tokenMap, "token", String.class);

		if (null == userInfo || StrUtil.isBlank(token)) {
			return toResponsFail("登录失败");
		}

		List<SsoWyUrl> urls = ssoWyUrlService.queryByUserId(userVo.getRelateIds());
		resultObj.put("wyUrl", urls);
		resultObj.put("token", token);
		resultObj.put("userInfo", userVo);
		resultObj.put("openid", sessionData.getString("openid"));
		return toResponsSuccess(resultObj);
	}

	/**
	 * 微信绑定
	 * 
	 * @param phone 手机号码
	 * @param cardnum 身份证后6位
	 * @param ids   物管类型
	 * @param token 微信token
	 * @param role  角色
	 * @return
	 */
	@ApiOperation(value = "微信绑定")
	@Log(title = "sso微信用户绑定", businessType = BusinessType.INSERT)
	@PostMapping("binding")
	@ResponseBody
	public String binding(String phone,String cardnum, String ids, String token, String role) {
		Map<String, Object> res = new HashMap<String, Object>();
		// 判断是否绑定

		SsoWxToken wxToken = ssoWxTokenService.queryByToken(token);

		if(ObjectUtil.isNull(wxToken)) {
			res.put("code", 1);
			res.put("msg", "请登录");
			return JSON.toJSONString(res);
		}
		 List<SsoWyUrl> SsoWyUrls = this.ssoWyUrlService.selectSsoWyUrlList(null);
		StringBuffer urls = new StringBuffer();
		for (SsoWyUrl SsoWyUrl : SsoWyUrls) {
			urls.append(SsoWyUrl.getId()+",");
		}
		ids = urls.substring(0,urls.length()-1);
		role =  role!=null ? role:"0";//默认为0业主
		
		boolean isBinding = ssoWxUserService.isBinding(wxToken.getUserId(), ids);
		if (isBinding) {
			res.put("code", 1);
			res.put("msg", "已绑定");
			return JSON.toJSONString(res);
		}
		// 绑定新的
		if (StrUtil.isNotBlank(phone)) {
			res = ssoWxUserService.binding(phone,cardnum, ids, token, role);
		}

		return JSON.toJSONString(res);
	}

	@ApiOperation(value = "微信解绑")
	@Log(title = "sso微信用户解绑", businessType = BusinessType.DELETE)
	@PostMapping("unbundle")
	@ResponseBody
	public String unbundle(String token) {
		Map<String, Object> res = new HashMap<String, Object>();
		SsoWxToken ssoWxToken = ssoWxTokenService.queryByToken(token);

		res = ssoWxUserService.unbundle(ssoWxToken.getUserId());

		return JSON.toJSONString(res);
	}

	/**
	 * 获取验证码
	 * 
	 * @return
	 */
	@PostMapping("getVerificationCode")
	@ResponseBody
	public String getVerificationCode() {

		return "维护中";
	}

	public JSONObject getJsonRequest() {
		JSONObject result = null;
		StringBuilder sb = new StringBuilder();
		try (BufferedReader reader = request.getReader();) {
			char[] buff = new char[1024];
			int len;
			while ((len = reader.read(buff)) != -1) {
				sb.append(buff, 0, len);
			}
			result = JSONObject.parseObject(sb.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}

		return result;
	}

	public Map<String, Object> toResponsFail(String msg) {
		return toResponsObject(1, msg, null);
	}

	/**
	 * @param requestCode
	 * @param msg
	 * @param data
	 * @return Map<String,Object>
	 * @throws @Description:构建统一格式返回对象
	 * @date 2016年9月2日
	 * @author zhuliyun
	 */
	public Map<String, Object> toResponsObject(int requestCode, String msg, Object data) {
		Map<String, Object> obj = new HashMap<String, Object>();
		obj.put("errno", requestCode);
		obj.put("errmsg", msg);
		if (data != null)
			obj.put("data", data);
		return obj;
	}

	/**
	 * 获取请求方IP
	 *
	 * @return 客户端Ip
	 */
	public String getClientIp() {
		String xff = request.getHeader("X-Real-IP");
		if (xff != null) {
			return xff;
		}
		xff = request.getHeader("x-forwarded-for");
		if (xff == null) {
			return "8.8.8.8";
		}
		return xff;
	}

	public Map<String, Object> toResponsSuccess(Object data) {
		Map<String, Object> rp = toResponsObject(0, "执行成功", data);
		logger.info("response:" + rp);
		return rp;
	}


}
